﻿using Model;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Model
{
    /// <summary>
    /// Http请求获取网络上的API数据
    /// </summary>
    public class HttpDataComponent : Component
    {
        public string uri = "https://api.zao28.com/News?name=xy28&type=json";
        private PlayType playType;
        public IDataParser DataParser { get; set; }

        private Queue<DateTime> nextTimes = new Queue<DateTime>(); // 开奖时间队列
        private Queue<DateTime> nextTimes2 = new Queue<DateTime>();

        // 当前数据的总期数
        private int issueCount = 0;

        private Queue<OpenData> datas = new Queue<OpenData>();

        private DateTime currTime; // 当前时间

        // 跳过的次数
        private int skipCount = 0;

        private bool isSkipComplete = false;

        private enum RequestState
        {
            Loading, // 开始获取,
            Reloading, // 重新获取
        }

        private RequestState state = RequestState.Loading;

        public void Awake(PlayType playType, Queue<DateTime> nextTimes)
        {
            this.currTime = DateTime.Now;
            this.playType = playType;
            this.nextTimes = nextTimes;

            // 算出来的时间项，就是一天的总期数。
            this.issueCount = nextTimes.Count;
        }

        public  void Start()
        {
            // 队列时间快进
           this.skipCount = SpeedTimeToCurrent();

            Log.Info($"下一次获取数据时间：{nextTimes.Peek().ToString()}");
            FixedUpdate();
        }

        /// <summary>
        /// 快进时间到当前
        /// </summary>
        /// <param name="queue"></param>
        public int SpeedTimeToCurrent()
        {
            int count = this.nextTimes.Count;
            for (int i = 0; i < count; i++)
            {
                DateTime dateTime = this.nextTimes.Peek();
                if (currTime.GT(dateTime))
                {
                    this.nextTimes2.Enqueue(this.nextTimes.Dequeue());
                }
                else
                {
                    return i;
                }
            }
            return 0;
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        public async void FixedUpdate()
        {
            while (true)
            {
                switch (state)
                {
                    case RequestState.Loading:
                        await Task.Delay(1000);
                        currTime = DateTime.Now;
                        if (nextTimes.Count == 0)
                            continue;
                        DateTime nextTime = nextTimes.Peek();
                        if (nextTime.GT(currTime))
                            continue;
                        await Load();
                        break;
                    case RequestState.Reloading:
                        await Load();
                        break;
                }
            }
        }

        public async Task Load()
        {
            try
            {
                // 获取数据
                string htmlText = await HttpHelper.GetAsyn(uri);
                OpenData openData = this.DataParser.Parse(htmlText);

                if (datas.Count > 0)
                {
                    long a = long.Parse(openData.Issue);
                    long b = long.Parse(datas.Peek().Issue);
                    if(a <= b)          //在网络极度慢的情况下，会出现跳期的情况。实现个在每天完成后，历史记录获取方法。
                    {
                        // 重新加载时，等待2秒。
                        await Task.Delay(2000);
                        state = RequestState.Reloading;
                        return;
                    }
                }
                datas.Enqueue(openData);
                state = RequestState.Loading;
                OnLoadSuccess(openData);
            }
            catch (Exception e)
            {
                // http错误
                Log.Error(e.Message);
            }

            nextTimes2.Enqueue(nextTimes.Dequeue());

            if (nextTimes.Count == 0)
            {
                // 开始处理没有获取到的期数不对的情况
                if(this.datas.Count != this.issueCount)
                {
                    Log.Error($"严重错误，情况获取数量不对！！！！需要获取：{this.issueCount}，已经获取：{this.datas.Count}");
                }
                // 交换
                var temp = nextTimes;
                nextTimes = nextTimes2;
                nextTimes2 = temp;

                // 数据存储数据库

            }

            Log.Info($"下一次获取数据时间：{nextTimes.Peek().ToString()}");

        }

        /// <summary>
        /// 计算开始期数
        /// </summary>
        public void ComputeStartIssue()
        {

            OpenData openData = datas.Peek();

            int tempIssue = int.Parse(openData.Issue);
            tempIssue -= this.skipCount;
            Log.Info("今天开始期数：" + tempIssue);
        }

        /// <summary>
        /// 获取成功后调用
        /// </summary>
        /// <param name="openData"></param>
        public void OnLoadSuccess(OpenData openData)
        {
            Log.Info(openData.ToJson());

            // 开始计算当天开始期数
            if (!isSkipComplete)
            {
                ComputeStartIssue();
                isSkipComplete = true;
            }
        }
    }
}